#include "utils.hpp"
#include <cstdio>

namespace util {
  void split(
        const std::string& src,
        const std::string& d,
        std::vector<std::string>& result) {
    // 空文字列だったとしても含める
    result.clear();
    std::string tmp = src;
    std::string::size_type pos = std::string::npos;
    while ((pos = tmp.find(d)) != std::string::npos) {
      result.push_back(tmp.substr(0, pos));
      tmp = tmp.substr(pos + d.length());  // pos は d の先頭，+length で次の標的
    }
    result.push_back(tmp);
  }

  std::string trim(const std::string& str) {
    if (str.empty()) {
      return str;
    }
    static const char WSs[] = " \t\r\n";
    std::string::size_type f = str.find_first_not_of(WSs);
    std::string::size_type l = str.find_last_not_of(WSs);
    if (f == std::string::npos) {
      return "";  // WSs しかない
    }
    return str.substr(f, l - f + 1);
  }

  const char* get_ext(const char* path) {
    const char* ext = path + strlen(path);
    while (ext != path && *(--ext) != '.');
    return *ext == '.' ? ++ext : NULL;
  }

  std::string to_string(const off_t size) {
    char buf[128];
    memset(buf, 0, sizeof(buf));
    sprintf(buf, "%ld", size);
    return std::string(buf);
  }

  // time 系
  namespace time {
    std::string get_date_str_rfc1123(const time_t& tt) {
      tm gmt;
      gmtime_r(&tt, &gmt);
      char buf[50]; memset(buf, 0, sizeof(buf));
      strftime(buf, sizeof(buf)-1, "%a, %d %b %Y %H:%M:%S %Z", &gmt);
      return std::string(buf);
    }

    std::string get_date_str_rfc1123() {
      time_t tt;
      ::time(&tt);
      return get_date_str_rfc1123(tt);
    }

    time_t parse_rfc1123(const char* str, const int isdst) {
      struct tm ret_tm;
      if (strptime(str, "%a, %d %b %Y %H:%M:%S GMT", &ret_tm) == NULL) {
        // ↑正常終了なら return '\0'
        return (time_t) -1;
      }
      ret_tm.tm_isdst = isdst;
      return mktime(&ret_tm);
    }
  }

  namespace debug {
    void debug_map(
          const char* bmsg,
          const std::map<std::string, std::string>& map,
          const char* emsg) {
      printf("[%s]>>\n", bmsg);
      for (std::map<std::string, std::string>::const_iterator it = map.begin();
           it != map.end();
           ++it) {
        printf("%s:%s\n", it->first.c_str(), it->second.c_str());
      }
      printf("<<[%s]\n", emsg);
    }
  }
} // end namespace util
